Imports System.Runtime.InteropServices

Public Class frmSplash
    Private Sub frmSplash_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        makeLayered()
    End Sub

    Private Sub makeLayered()
        Dim InitialStyle As Integer = Win32.GetWindowLong(Handle, Win32.GWL.ExStyle)
        If InitialStyle = 0 Then
            Throw New Exception("GetWindowLong " & Win32.GetLastError)
        End If

        If Win32.SetWindowLong(Handle, Win32.GWL.ExStyle, CType(InitialStyle Or Win32.WS_EX.Layered Or Win32.WS_EX.Transparent, Win32.WS_EX)) = 0 Then
            Throw New Exception("SetWindowLong " & Win32.GetLastError)
        End If

        Dim screenDc As IntPtr = Win32.GetDC(IntPtr.Zero)
        If screenDc = IntPtr.Zero Then
            Throw New Exception("GetDC " & Win32.GetLastError)
        End If

        Dim memDc As IntPtr = Win32.CreateCompatibleDC(screenDc)
        If memDc = IntPtr.Zero Then
            Throw New Exception("CreateCompatibleDC " & Win32.GetLastError)
        End If

        Dim hBitmap As IntPtr = IntPtr.Zero
        Dim oldBitmap As IntPtr = IntPtr.Zero

        Dim bmp As Bitmap = New Bitmap(Me.BackgroundImage)

        Try
            hBitmap = bmp.GetHbitmap(Color.FromArgb(0)) ' grab a GDI handle from this GDI+ bitmap

            oldBitmap = Win32.SelectObject(memDc, hBitmap)
            If oldBitmap = IntPtr.Zero Then
                Throw New Exception("SelectObject " & Win32.GetLastError)
            End If

            Dim blend As New Win32.BLENDFUNCTION
            blend.BlendOp = Win32.AC_SRC_OVER
            blend.BlendFlags = 0
            blend.SourceConstantAlpha = 255
            blend.AlphaFormat = Win32.AC_SRC_ALPHA

            Dim szNewSize As New Win32.Size(Size.Width, Size.Height)
            Dim ptNewLocation As New Win32.Point(Left, Top)
            Dim ptSourceLocation As New Win32.Point(0, 0)

            If Not Win32.UpdateLayeredWindow(Handle, screenDc, ptNewLocation, szNewSize, memDc, ptSourceLocation, 0, blend, Win32.ULW_ALPHA) Then
                Throw New Exception("UpdateLayeredWindow " & Win32.GetLastError)
            End If
        Finally
            If Win32.ReleaseDC(IntPtr.Zero, screenDc) = 0 Then
                Throw New Exception("ReleaseDC " & Win32.GetLastError)
            End If

            If hBitmap <> IntPtr.Zero Then
                If Win32.SelectObject(memDc, oldBitmap) = IntPtr.Zero Then
                    Throw New Exception("SelectObject " & Win32.GetLastError)
                End If

                If Not Win32.DeleteObject(hBitmap) Then
                    Throw New Exception("DeleteObject " & Win32.GetLastError)
                End If
            End If
        End Try

        If Not Win32.DeleteDC(memDc) Then
            Throw New Exception("DeleteDC " & Win32.GetLastError)
        End If
    End Sub
End Class

Public Class Win32
    Public Enum GWL As Integer
        ExStyle = -20
    End Enum

    Public Enum WS_EX As Integer
        Transparent = &H20
        Layered = &H80000
    End Enum

    Public Enum LWA As Integer
        ColorKey = &H1
        Alpha = &H2
    End Enum

    <DllImport("user32.dll", EntryPoint:="GetWindowLong")> _
    Public Shared Function GetWindowLong( _
        ByVal hWnd As IntPtr, _
        ByVal nIndex As GWL _
            ) As Integer
    End Function

    <DllImport("user32.dll", EntryPoint:="SetWindowLong")> _
    Public Shared Function SetWindowLong( _
        ByVal hWnd As IntPtr, _
        ByVal nIndex As GWL, _
        ByVal dwNewLong As WS_EX _
            ) As Integer
    End Function

    <StructLayout(LayoutKind.Sequential, Pack:=1)> _
    Public Structure BLENDFUNCTION
        Public BlendOp As Byte
        Public BlendFlags As Byte
        Public SourceConstantAlpha As Byte
        Public AlphaFormat As Byte
    End Structure

    Public Const AC_SRC_OVER As Byte = &H0
    Public Const AC_SRC_ALPHA As Byte = &H1
    Public Const ULW_ALPHA As Int32 = &H2

    <StructLayout(LayoutKind.Sequential)> _
    Public Structure Point
        Public x As Int32
        Public y As Int32

        Public Sub New(ByVal pX As Int32, ByVal pY As Int32)
            x = pX
            y = pY
        End Sub
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Public Structure Size
        Public cx As Int32
        Public cy As Int32

        Public Sub New(ByVal pCX As Int32, ByVal pCY As Int32)
            cx = pCX
            cy = pCY
        End Sub
    End Structure

    <DllImport("user32.dll", _
      EntryPoint:="UpdateLayeredWindow")> _
    Public Shared Function UpdateLayeredWindow(ByVal handle As IntPtr, ByVal hdcDst As IntPtr, ByRef pptDst As Point, ByRef psize As Size, ByVal hdcSrc As IntPtr, ByRef pprSrc As Point, ByVal crKey As Integer, ByRef pblend As BLENDFUNCTION, ByVal dwFlags As Integer) As Boolean
    End Function

    <DllImport("user32.dll", _
      EntryPoint:="GetDC")> _
    Public Shared Function GetDC(ByVal hWnd As IntPtr) As IntPtr
    End Function

    <DllImport("gdi32.dll", _
    EntryPoint:="CreateCompatibleDC")> _
    Public Shared Function CreateCompatibleDC(ByVal hDC As IntPtr) As IntPtr
    End Function

    <DllImport("gdi32.dll", _
    EntryPoint:="SelectObject")> _
    Public Shared Function SelectObject(ByVal hDC As IntPtr, ByVal hObject As IntPtr) As IntPtr
    End Function

    <DllImport("user32.dll", _
    EntryPoint:="ReleaseDC")> _
    Public Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As Integer
    End Function

    <DllImport("gdi32.dll", _
    EntryPoint:="DeleteObject")> _
    Public Shared Function DeleteObject(ByVal hObject As IntPtr) As Boolean
    End Function

    <DllImport("gdi32.dll", _
    EntryPoint:="DeleteDC")> _
    Public Shared Function DeleteDC(ByVal hdc As IntPtr) As Boolean
    End Function

    <DllImport("kernel32.dll", _
    EntryPoint:="GetLastError")> _
    Public Shared Function GetLastError() As Integer
    End Function
End Class

